<template>
    <div class="common-layout">
        <el-container>
            <el-header>
                <div class="search-container">
                    <el-form ref="queryFormRef" :model="queryParams" :inline="true">
                        <el-form-item prop="keywords" label="关键字">
                            <el-input v-model="queryParams.keywords" placeholder="角色名称" clearable
                                @keyup.enter="handleQuery" />
                        </el-form-item>

                        <el-form-item>
                            <el-button type="primary" @click="handleQuery"><i-ep-search />搜索</el-button>
                            <el-button @click="handleResetQuery"><i-ep-refresh />重置</el-button>
                        </el-form-item>
                    </el-form>
                </div>
            </el-header>
            <el-main>
                <el-button type="success" @click="openDialog()"><i-ep-plus />新增</el-button>
                <el-button type="danger" @click="handleDelete()"
                    :disabled="ids.length === 0"><i-ep-delete />删除</el-button>
                <el-table :data="roleList" row-key="id" style="width: 100%" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="55" align="center" />
                    <el-table-column prop="name" label="角色名称" width="630" />
                    <el-table-column prop="code" label="角色编码" width="150" />
                    <el-table-column label="状态" align="center" width="100">
                        <template #default="scope">
                            <el-tag v-if="scope.row.status === 1" type="success">正常</el-tag>
                            <el-tag v-else type="info">禁用</el-tag>
                        </template>
                    </el-table-column>
                    <el-table-column label="排序" align="center" prop="sort" width="80" />
                    <el-table-column fixed="right" label="操作" width="220">
                        <template #default="scope">
                            <el-button link type="primary" size="small" @click="openMenuDialog(scope.row)">
                                <i-ep-position />分配权限
                            </el-button>
                            <el-button link type="primary" size="small" @click="openDialog(scope.row.id)">
                                <i-ep-edit />编辑
                            </el-button>
                            <el-button link type="primary" size="small" @click.stop="handleDelete(scope.row.id)">
                                <i-ep-delete />删除
                            </el-button>
                        </template>
                    </el-table-column>
                </el-table>
                <!-- 分页 -->
                <el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize"
                    :page-sizes="[1, 3, 5, 10]" :small="false" :disabled="false" :background="true"
                    layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange"
                    @current-change="handleCurrentChange" />

                <!-- 角色表单弹窗 -->
                <el-dialog v-model="dialog.visible" :title="dialog.title" width="500px" @close="closeDialog">
                    <el-form ref="roleFormRef" :model="formData" :rules="rules" label-width="100px">
                        <el-form-item label="角色名称" prop="name">
                            <el-input v-model="formData.name" placeholder="请输入角色名称" />
                        </el-form-item>

                        <el-form-item label="角色编码" prop="code">
                            <el-input v-model="formData.code" placeholder="请输入角色编码" />
                        </el-form-item>

                        <el-form-item label="数据权限" prop="dataScope">
                            <el-select v-model="formData.dataScope">
                                <el-option :key="0" label="全部数据" :value="0" />
                                <el-option :key="1" label="部门及子部门数据" :value="1" />
                                <el-option :key="2" label="本部门数据" :value="2" />
                                <el-option :key="3" label="本人数据" :value="3" />
                            </el-select>
                        </el-form-item>

                        <el-form-item label="状态" prop="status">
                            <el-radio-group v-model="formData.status">
                                <el-radio :label="1">正常</el-radio>
                                <el-radio :label="0">停用</el-radio>
                            </el-radio-group>
                        </el-form-item>

                        <el-form-item label="排序" prop="sort">
                            <el-input-number v-model="formData.sort" controls-position="right" :min="0"
                                style="width: 100px" />
                        </el-form-item>
                    </el-form>

                    <template #footer>
                        <div class="dialog-footer">
                            <el-button type="primary" @click="handleSubmit">确 定</el-button>
                            <el-button @click="closeDialog">取 消</el-button>
                        </div>
                    </template>
                </el-dialog>

                <!-- 分配菜单弹窗  -->
                <el-dialog v-model="menuDialogVisible" :title="'【' + checkedRole.name + '】权限分配'" width="800px">
                    <el-scrollbar v-loading="loading" max-height="600px">
                        <el-tree ref="menuRef" node-key="value" show-checkbox :data="menuList"
                            :default-expand-all="true">
                            <template #default="{ data }">
                                {{ data.label }}
                            </template>
                        </el-tree>
                    </el-scrollbar>

                    <template #footer>
                        <div class="dialog-footer">
                            <el-button type="primary" @click="handleRoleMenuSubmit">确 定</el-button>
                            <el-button @click="menuDialogVisible = false">取 消</el-button>
                        </div>
                    </template>
                </el-dialog>
            </el-main>
        </el-container>
    </div>
</template>

<script setup lang="ts">
// 调用接口
import { getPage, getOptionss, getRoleMenuIds, updateRoleMenus, getFormData, add, update, deleteByIds } from '@/api/role/index';
import { getRoutes, getList, getOptions } from '@/api/menu/index';
// 调用类型
import type { RolePageVO, RoleForm, RoleQuery } from '@/api/role/model';
import type { OptionType } from 'element-plus/es/components/select-v2/src/select.types.mjs';

defineOptions({
    name: "Role",
    inheritAttrs: false,
});
const queryFormRef = ref(ElForm);
const roleFormRef = ref(ElForm);
const menuRef = ref(ElTree);

const loading = ref(false);
const ids = ref<number[]>([]);
const total = ref(0);

const queryParams = reactive<RoleQuery>({
    pageNum: 1,
    pageSize: 10,
});
// 分页
const handleSizeChange = (val: number) => {
    queryParams.pageSize = val
    //   console.log(`${val} items per page`)
    handleQuery()
}
const handleCurrentChange = (val: number) => {
    queryParams.pageNum = val
    //   console.log(`current page: ${val}`)
    handleQuery()
}

const roleList = ref<RolePageVO[]>();

const dialog = reactive({
    title: "",
    visible: false,
});

const formData = reactive<RoleForm>({
    sort: 1,
    status: 1,
    code: "",
    name: "",
});

const rules = reactive({
    name: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
    code: [{ required: true, message: "请输入角色编码", trigger: "blur" }],
    dataScope: [{ required: true, message: "请选择数据权限", trigger: "blur" }],
    status: [{ required: true, message: "请选择状态", trigger: "blur" }],
});

const menuDialogVisible = ref(false);

const menuList = ref<OptionType[]>([]);

interface CheckedRole {
    id?: number;
    name?: string;
}
let checkedRole: CheckedRole = reactive({});

/** 查询 */
async function handleQuery() {
    loading.value = true;
    await getPage(queryParams)
        .then((data) => {
            roleList.value = data.list;
            total.value = data.total;
        })
        .finally(() => {
            loading.value = false;
        });
}
/** 重置查询 */
function handleResetQuery() {
    queryFormRef.value.resetFields();
    queryParams.pageNum = 1;
    handleQuery();
}

/** 行checkbox 选中事件 */
function handleSelectionChange(selection: any) {
    ids.value = selection.map((item: any) => item.id);
}

/** 打开角色表单弹窗 */
function openDialog(roleId?: number) {
    dialog.visible = true;
    if (roleId) {
        dialog.title = "修改角色";
        getFormData(roleId).then((data) => {
            Object.assign(formData, data);
        });
    } else {
        dialog.title = "新增角色";
    }
}

/** 角色保存提交 */
function handleSubmit() {
    roleFormRef.value.validate((valid: any) => {
        if (valid) {
            loading.value = true;
            const roleId = formData.id;
            if (roleId) {
                update(roleId, formData)
                    .then(() => {
                        ElMessage.success("修改成功");
                        closeDialog();
                        handleResetQuery();
                    })
                    .finally(() => (loading.value = false));
            } else {
                add(formData)
                    .then(() => {
                        ElMessage.success("新增成功");
                        closeDialog();
                        handleResetQuery();
                    })
                    .finally(() => (loading.value = false));
            }
        }
    });
}

/** 关闭表单弹窗 */
function closeDialog() {
    dialog.visible = false;
    resetForm();
}

/** 重置表单 */
function resetForm() {
    roleFormRef.value.resetFields();
    roleFormRef.value.clearValidate();

    formData.id = undefined;
    formData.sort = 1;
    formData.status = 1;
}

/** 删除角色 */
function handleDelete(roleId?: number) {
    const roleIds = [roleId || ids.value].join(",");
    if (!roleIds) {
        ElMessage.warning("请勾选删除项");
        return;
    }

    ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
    }).then(() => {
        loading.value = true;
        deleteByIds(roleIds)
            .then(() => {
                ElMessage.success("删除成功");
                handleResetQuery();
            })
            .finally(() => (loading.value = false));
    });
}

/** 打开分配菜单弹窗 */
async function openMenuDialog(row: RolePageVO) {
    const roleId = row.id;
    if (roleId) {
        checkedRole = {
            id: roleId,
            name: row.name,
        };
        menuDialogVisible.value = true;
        loading.value = true;

        // 获取所有的菜单
        menuList.value = await getOptions();

        // 回显角色已拥有的菜单
        await getRoleMenuIds(roleId)
            .then((data) => {
                const checkedMenuIds = data;
                checkedMenuIds.forEach((menuId) =>
                    menuRef.value.setChecked(menuId, true, false)
                );
            })
            .finally(() => {
                loading.value = false;
            });
    }
}

/** 角色分配菜单保存提交 */
function handleRoleMenuSubmit() {
    const roleId = checkedRole.id;
    if (roleId) {
        const checkedMenuIds: number[] = menuRef.value
            .getCheckedNodes(false, true)
            .map((node: any) => node.value);

        loading.value = true;
        updateRoleMenus(roleId, checkedMenuIds)
            .then(() => {
                ElMessage.success("分配权限成功");
                menuDialogVisible.value = false;
                handleResetQuery();
            })
            .finally(() => {
                loading.value = false;
            });
    }
}

onMounted(() => {
    handleQuery();
});

</script>

<style scoped>
.el-header {
    background-color: white;
    padding: 12px 30px;
    box-sizing: border-box;
}

.el-main {
    background-color: white;
    margin-top: 20px;
}

.el-pagination {
    margin-top: 20px;
}
</style>